using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;

namespace AvaloniaInfiniteScrolling;

// https://github.com/Coolkeke/LayUI-Avalonia/blob/main/src/LayuiAvaloniaPack/UI/LayUI.Avalonia/Controls/ItemsControl/LayFlowItemsControl.cs
[TemplatePart(Name = nameof(PART_ScrollViewer), Type = typeof(ScrollViewer))]
public class AvaloniaInfiniteScrollControl : ItemsControl {
    private ScrollViewer PART_ScrollViewer;

    protected override void OnApplyTemplate(TemplateAppliedEventArgs e) {
        base.OnApplyTemplate(e);
        PART_ScrollViewer = e.NameScope.Find<ScrollViewer>(nameof(PART_ScrollViewer));
        if (PART_ScrollViewer != null) {
            PART_ScrollViewer.ScrollChanged -= PART_ScrollViewer_ScrollChanged;
            PART_ScrollViewer.ScrollChanged += PART_ScrollViewer_ScrollChanged;
        }
    }

    private async void PART_ScrollViewer_ScrollChanged(object? sender, ScrollChangedEventArgs e) {
        if (PART_ScrollViewer == null) {
            return;
        }

        if (ItemsSource == null) {
            PART_ScrollViewer.ScrollToHome();
            return;
        }

        if (PART_ScrollViewer.ScrollBarMaximum.Y != PART_ScrollViewer.Offset.Y) {
            return;
        }

        if (ItemsSource is not IAvaloniaInfiniteScrollCollection infiniteScrollCollection) {
            return;
        }

        if (infiniteScrollCollection.IsLoadingMore) {
            return;
        }

        do {
            if (!infiniteScrollCollection.CanLoadMore) {
                return;
            }

            await infiniteScrollCollection.LoadMoreAsync();
        } while (PART_ScrollViewer.ScrollBarMaximum.Y == PART_ScrollViewer.Offset.Y);
    }
}